PRÁCTICA 1: APRENDIZAJE NO SUPERVISADO (DengAI)
Nombre y apellidos: Carla Daniela Di Monno
Usuario VIU: cdimonno@student.universidadviu.com
Contexto¶
El dengue es una enfermedad viral transmitida por mosquitos, especialmente común en regiones tropicales y subtropicales. Sus síntomas varían desde leves hasta graves, e incluso pueden ser mortales. La transmisión del dengue se ve influenciada por factores climáticos como la temperatura y las precipitaciones, lo que hace que el clima sea un factor determinante en su propagación.
Ante el cambio climático, se espera que la distribución geográfica del dengue se expanda, afectando a nuevas poblaciones. Para abordar este desafío, se ha creado la competencia DengAI. En esta competencia, el objetivo es desarrollar modelos capaces de predecir el número semanal de casos de dengue en San Juan (Puerto Rico) e Iquitos (Perú), utilizando datos climáticos y ambientales proporcionados por agencias gubernamentales de EE.UU. como los Centros para el Control y Prevención de Enfermedades (CDC) y la Administración Nacional Oceánica y Atmosférica (NOAA).
Al analizar estos datos, se busca comprender cómo variables como la temperatura, las precipitaciones y la vegetación influyen en los brotes de dengue. Esta información es crucial para mejorar la capacidad de predicción y, por lo tanto, optimizar la asignación de recursos en las iniciativas de salud pública destinadas a prevenir y controlar futuros brotes. Además, este enfoque contribuye a los esfuerzos globales para anticipar y mitigar pandemias.
Objetivo¶
El objetivo de esta práctica es explorar los datos de la competencia DengAI mediante técnicas de minería de datos y aprendizaje no supervisado, en conjunto con la ingeniería de características. Se busca identificar patrones y características relevantes para mejorar la predicción de casos de dengue, incluyendo la selección de variables, la aplicación de clustering y la evaluación de nuevas variables.
Fases experimentación y resultados obtenidos¶
Este trabajo se enfoca en explorar y analizar diversas metodologías de clustering en el ámbito del aprendizaje no supervisado, con el objetivo de agrupar objetos similares en conjuntos o clústeres. En particular, se aplicarán y compararán cuatro técnicas de clustering: Clustering Jerárquico Aglomerativo, K-Means, DBSCAN y GMM (Expectation-Maximization), utilizando un conjunto de datos de entrenamiento previamente preprocesado.
El proceso se inicia con un análisis exhaustivo de los datos, incluyendo la minería de datos y el preprocesado. Se realiza un análisis inicial para comprender la estructura y características de los datos, seguido de filtros y transformaciones necesarias. Se lleva a cabo una estadística descriptiva inicial y se aborda el tratamiento de valores faltantes y outliers. Posteriormente, se realiza una ingeniería avanzada de características, creando nuevas características a partir de las existentes e identificando aquellas más relevantes y eliminando las que no aportan valor a partir del clustering aplicado al dataset traspuesto. Luego, se aplican los algoritmos de clustering mencionados al dataset preprocesado para identificar patrones, agrupaciones y relaciones en los datos. Finalmente, se extraen conclusiones significativas que resumen los hallazgos obtenidos del análisis de datos y los algoritmos de clustering aplicados. Este enfoque integral nos permitirá obtener una comprensión más profunda de los datos y generar conocimiento relevante para abordar el desafío planteado en este trabajo: "DengAI: Predicting Disease Spread".
# Imports generales
import pandas as pd
import numpy as np
import io
import math
from google.colab import files
# Visualización de datos / Gráficos
import seaborn as sns
import matplotlib.pyplot as plt
# Preprocesamiento
from sklearn.preprocessing import MinMaxScaler, StandardScaler
# Preprocesamiento / Modelado
from sklearn.decomposition import PCA
from scipy import cluster
from scipy.cluster.hierarchy import dendrogram, linkage
from sklearn.cluster import DBSCAN, AgglomerativeClustering, KMeans
from sklearn.neighbors import NearestNeighbors
from sklearn import metrics
from sklearn.metrics import silhouette_score
from sklearn.mixture import GaussianMixture
seed = 42 # Semilla aleatoria arbitraria y constante a incluir en los algoritmos estocásticos para que los experimentos sean siempre reproducibles por el profesor.
# OJO: En los experimentos estocásticos que requieran varias iteraciones con distintas semillas, podéis incorporarla como seed+1, seed+2, etc.
def upload_files (index_fields=None):
uploaded = files.upload()
for fn in uploaded.keys():
print('User uploaded file "{name}" with length {length} bytes'.format(
name=fn, length=len(uploaded[fn])))
df = pd.read_csv(io.StringIO(uploaded[fn].decode('utf-8')), index_col = index_fields)
return df
# Subir el conjunto de entrenamiento sin variable objetivo (dengue_features_train.csv)
train = upload_files()
print(train.shape)
train.head()
Saving dengue_features_train (1).csv to dengue_features_train (1).csv User uploaded file "dengue_features_train (1).csv" with length 287139 bytes (1456, 24)
| city | year | weekofyear | week_start_date | ndvi_ne | ndvi_nw | ndvi_se | ndvi_sw | precipitation_amt_mm | reanalysis_air_temp_k | ... | reanalysis_precip_amt_kg_per_m2 | reanalysis_relative_humidity_percent | reanalysis_sat_precip_amt_mm | reanalysis_specific_humidity_g_per_kg | reanalysis_tdtr_k | station_avg_temp_c | station_diur_temp_rng_c | station_max_temp_c | station_min_temp_c | station_precip_mm | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | sj | 1990 | 18 | 1990-04-30 | 0.122600 | 0.103725 | 0.198483 | 0.177617 | 12.42 | 297.572857 | ... | 32.00 | 73.365714 | 12.42 | 14.012857 | 2.628571 | 25.442857 | 6.900000 | 29.4 | 20.0 | 16.0 |
| 1 | sj | 1990 | 19 | 1990-05-07 | 0.169900 | 0.142175 | 0.162357 | 0.155486 | 22.82 | 298.211429 | ... | 17.94 | 77.368571 | 22.82 | 15.372857 | 2.371429 | 26.714286 | 6.371429 | 31.7 | 22.2 | 8.6 |
| 2 | sj | 1990 | 20 | 1990-05-14 | 0.032250 | 0.172967 | 0.157200 | 0.170843 | 34.54 | 298.781429 | ... | 26.10 | 82.052857 | 34.54 | 16.848571 | 2.300000 | 26.714286 | 6.485714 | 32.2 | 22.8 | 41.4 |
| 3 | sj | 1990 | 21 | 1990-05-21 | 0.128633 | 0.245067 | 0.227557 | 0.235886 | 15.36 | 298.987143 | ... | 13.90 | 80.337143 | 15.36 | 16.672857 | 2.428571 | 27.471429 | 6.771429 | 33.3 | 23.3 | 4.0 |
| 4 | sj | 1990 | 22 | 1990-05-28 | 0.196200 | 0.262200 | 0.251200 | 0.247340 | 7.52 | 299.518571 | ... | 12.20 | 80.460000 | 7.52 | 17.210000 | 3.014286 | 28.942857 | 9.371429 | 35.0 | 23.9 | 5.8 |
5 rows × 24 columns
train.tail()
| city | year | weekofyear | week_start_date | ndvi_ne | ndvi_nw | ndvi_se | ndvi_sw | precipitation_amt_mm | reanalysis_air_temp_k | ... | reanalysis_precip_amt_kg_per_m2 | reanalysis_relative_humidity_percent | reanalysis_sat_precip_amt_mm | reanalysis_specific_humidity_g_per_kg | reanalysis_tdtr_k | station_avg_temp_c | station_diur_temp_rng_c | station_max_temp_c | station_min_temp_c | station_precip_mm | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1451 | iq | 2010 | 21 | 2010-05-28 | 0.342750 | 0.318900 | 0.256343 | 0.292514 | 55.30 | 299.334286 | ... | 45.00 | 88.765714 | 55.30 | 18.485714 | 9.800000 | 28.633333 | 11.933333 | 35.4 | 22.4 | 27.0 |
| 1452 | iq | 2010 | 22 | 2010-06-04 | 0.160157 | 0.160371 | 0.136043 | 0.225657 | 86.47 | 298.330000 | ... | 207.10 | 91.600000 | 86.47 | 18.070000 | 7.471429 | 27.433333 | 10.500000 | 34.7 | 21.7 | 36.6 |
| 1453 | iq | 2010 | 23 | 2010-06-11 | 0.247057 | 0.146057 | 0.250357 | 0.233714 | 58.94 | 296.598571 | ... | 50.60 | 94.280000 | 58.94 | 17.008571 | 7.500000 | 24.400000 | 6.900000 | 32.2 | 19.2 | 7.4 |
| 1454 | iq | 2010 | 24 | 2010-06-18 | 0.333914 | 0.245771 | 0.278886 | 0.325486 | 59.67 | 296.345714 | ... | 62.33 | 94.660000 | 59.67 | 16.815714 | 7.871429 | 25.433333 | 8.733333 | 31.2 | 21.0 | 16.0 |
| 1455 | iq | 2010 | 25 | 2010-06-25 | 0.298186 | 0.232971 | 0.274214 | 0.315757 | 63.22 | 298.097143 | ... | 36.90 | 89.082857 | 63.22 | 17.355714 | 11.014286 | 27.475000 | 9.900000 | 33.7 | 22.2 | 20.4 |
5 rows × 24 columns
En esta sección primero se busca tener una idea general de cómo son los datos y cómo están distribuidos, etc., realizando un análisis exploratorio de los datos que consiste en obtener el análisis estadístico descriptivo de los datos y visualizar el comportamiento y relaciones de las variables mediante distintos gráficos. Para ello se implementa fragmentos de código que he utilizado previamente en mis prácticas de Minería de Datos y en algunos casos el asistente Gemini(IA) del Google Colab.
Análisis Exploratorio de Datos (EDA)¶
Dataset completo¶
# Obtener información sobre la BBDD dengue_features_train (tamaño, características, tipos de datos, etc.)
train.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 1456 entries, 0 to 1455 Data columns (total 24 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 city 1456 non-null object 1 year 1456 non-null int64 2 weekofyear 1456 non-null int64 3 week_start_date 1456 non-null object 4 ndvi_ne 1262 non-null float64 5 ndvi_nw 1404 non-null float64 6 ndvi_se 1434 non-null float64 7 ndvi_sw 1434 non-null float64 8 precipitation_amt_mm 1443 non-null float64 9 reanalysis_air_temp_k 1446 non-null float64 10 reanalysis_avg_temp_k 1446 non-null float64 11 reanalysis_dew_point_temp_k 1446 non-null float64 12 reanalysis_max_air_temp_k 1446 non-null float64 13 reanalysis_min_air_temp_k 1446 non-null float64 14 reanalysis_precip_amt_kg_per_m2 1446 non-null float64 15 reanalysis_relative_humidity_percent 1446 non-null float64 16 reanalysis_sat_precip_amt_mm 1443 non-null float64 17 reanalysis_specific_humidity_g_per_kg 1446 non-null float64 18 reanalysis_tdtr_k 1446 non-null float64 19 station_avg_temp_c 1413 non-null float64 20 station_diur_temp_rng_c 1413 non-null float64 21 station_max_temp_c 1436 non-null float64 22 station_min_temp_c 1442 non-null float64 23 station_precip_mm 1434 non-null float64 dtypes: float64(20), int64(2), object(2) memory usage: 273.1+ KB
El datset original de entrenamiento dengue_features_train.csv contiene 1456 instancias y 24 características. En este enlace se puede ver una descripción de qué significan las características del dataset: https://www.drivendata.org/competitions/44/dengai-predicting-disease-spread/page/82/.
Según se observa en el enlace, las características brindan una escala de tiempo con la fecha de las mediciones, temperaturas, rango de temperaturas, precipitación, humedad relativa, humedad específica y el índice 'ndvi' que se relaciona con información sobre la densidad de vegetación en los puntos cardinales de las ciudades. Específicamente 'ndvi' es el Índice de Vegetación de Diferencia Normalizada, mide la cantidad y salud de la vegetación en una superficie, basado en la reflectancia de la luz en diferentes longitudes de onda. Toma valores entre -1 y 1, donde valores más altos indican una vegetación más saludable y valores bajos o negativos pueden indicar estrés vegetal o ausencia de vegetación (ref.:cursosteledetección).
De la información obtenida del dataframe vemos que las 4 primeras variables no tiene valores faltantes y que las columnas 'city' y 'week_start_date' son de tipo objeto, mientras que el resto son numéricas. Siendo solo 'year' y 'weekofyear' enteras y el resto reales, representadas en punto flotante.
Estadísticas generales iniciales¶
# Estadística descriptiva de características numéricas climatológicas y ambientales (no nulos, media, desviación estándar, mínimo, percentiles, máximo)
train.describe(include=['float64'])
| ndvi_ne | ndvi_nw | ndvi_se | ndvi_sw | precipitation_amt_mm | reanalysis_air_temp_k | reanalysis_avg_temp_k | reanalysis_dew_point_temp_k | reanalysis_max_air_temp_k | reanalysis_min_air_temp_k | reanalysis_precip_amt_kg_per_m2 | reanalysis_relative_humidity_percent | reanalysis_sat_precip_amt_mm | reanalysis_specific_humidity_g_per_kg | reanalysis_tdtr_k | station_avg_temp_c | station_diur_temp_rng_c | station_max_temp_c | station_min_temp_c | station_precip_mm | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| count | 1262.000000 | 1404.000000 | 1434.000000 | 1434.000000 | 1443.000000 | 1446.000000 | 1446.000000 | 1446.000000 | 1446.000000 | 1446.000000 | 1446.000000 | 1446.000000 | 1443.000000 | 1446.000000 | 1446.000000 | 1413.000000 | 1413.000000 | 1436.000000 | 1442.000000 | 1434.000000 |
| mean | 0.142294 | 0.130553 | 0.203783 | 0.202305 | 45.760388 | 298.701852 | 299.225578 | 295.246356 | 303.427109 | 295.719156 | 40.151819 | 82.161959 | 45.760388 | 16.746427 | 4.903754 | 27.185783 | 8.059328 | 32.452437 | 22.102150 | 39.326360 |
| std | 0.140531 | 0.119999 | 0.073860 | 0.083903 | 43.715537 | 1.362420 | 1.261715 | 1.527810 | 3.234601 | 2.565364 | 43.434399 | 7.153897 | 43.715537 | 1.542494 | 3.546445 | 1.292347 | 2.128568 | 1.959318 | 1.574066 | 47.455314 |
| min | -0.406250 | -0.456100 | -0.015533 | -0.063457 | 0.000000 | 294.635714 | 294.892857 | 289.642857 | 297.800000 | 286.900000 | 0.000000 | 57.787143 | 0.000000 | 11.715714 | 1.357143 | 21.400000 | 4.528571 | 26.700000 | 14.700000 | 0.000000 |
| 25% | 0.044950 | 0.049217 | 0.155087 | 0.144209 | 9.800000 | 297.658929 | 298.257143 | 294.118929 | 301.000000 | 293.900000 | 13.055000 | 77.177143 | 9.800000 | 15.557143 | 2.328571 | 26.300000 | 6.514286 | 31.100000 | 21.100000 | 8.700000 |
| 50% | 0.128817 | 0.121429 | 0.196050 | 0.189450 | 38.340000 | 298.646429 | 299.289286 | 295.640714 | 302.400000 | 296.200000 | 27.245000 | 80.301429 | 38.340000 | 17.087143 | 2.857143 | 27.414286 | 7.300000 | 32.800000 | 22.200000 | 23.850000 |
| 75% | 0.248483 | 0.216600 | 0.248846 | 0.246982 | 70.235000 | 299.833571 | 300.207143 | 296.460000 | 305.500000 | 297.900000 | 52.200000 | 86.357857 | 70.235000 | 17.978214 | 7.625000 | 28.157143 | 9.566667 | 33.900000 | 23.300000 | 53.900000 |
| max | 0.508357 | 0.454429 | 0.538314 | 0.546017 | 390.600000 | 302.200000 | 302.928571 | 298.450000 | 314.000000 | 299.900000 | 570.500000 | 98.610000 | 390.600000 | 20.461429 | 16.028571 | 30.800000 | 15.800000 | 42.200000 | 25.600000 | 543.300000 |
A primera vista las estadísticas del dataset "parecieran estar bien", entonces para tener un mejor entendimiento de los datos nos conviene visualizarlos mediante gráficos.
Diagrama de barras variables categóricas¶
# Diagrama de barras de la variable categórica 'city'
sns.countplot(data=train, x='city')
plt.show()
Del gráfico de barras anterior se observa que la variable 'city' está desbalanceada. Es decir, tenemos más datos de prueba para la ciudad de San Juan que de Iquitos. Esto puede afectar la calidad de los modelos predictivos y su precisión, ya que puede no predecir correctamente los datos menos representados si consideramos usar todo en conjunto. Pero, ¿en qué se diferencian las ciudades de San Juan e Iquitos? Es muy probable que el comportamiento de la enfermedad en ambas ciudades sea distinto, debido a diferencias climáticas y ambientales, como por ejemplo clima más seco y clima húmedo, por lo tanto más adelante sería conveniente dividir el dataset.
Transformación variable categórica a numérica¶
La variable categórica 'city' registra la ciudad donde se tomaron los datos. Dado que el conjunto de datos solo incluye dos ciudades, San Juan e Iquitos, se asignará el valor 0 a San Juan y el valor 1 a la otra ciudad, Iquitos, para poder realizar cálculos.
# Mapear variable categórica 'city' a numérica
train['city_mapped'] = train['city'].map({'sj': 0, 'iq': 1})
print(train[['city', 'city_mapped']])
city city_mapped 0 sj 0 1 sj 0 2 sj 0 3 sj 0 4 sj 0 ... ... ... 1451 iq 1 1452 iq 1 1453 iq 1 1454 iq 1 1455 iq 1 [1456 rows x 2 columns]
# También podría haber binarizado la variable categórica city con la siguiente función
#from sklearn import preprocessing
#lb = preprocessing.LabelBinarizer()
#train['city_bin'] = lb.fit_transform(train['city'])
train['city'] = train['city_mapped']
train.drop('city_mapped', axis=1, inplace=True)
train.head()
| city | year | weekofyear | week_start_date | ndvi_ne | ndvi_nw | ndvi_se | ndvi_sw | precipitation_amt_mm | reanalysis_air_temp_k | ... | reanalysis_precip_amt_kg_per_m2 | reanalysis_relative_humidity_percent | reanalysis_sat_precip_amt_mm | reanalysis_specific_humidity_g_per_kg | reanalysis_tdtr_k | station_avg_temp_c | station_diur_temp_rng_c | station_max_temp_c | station_min_temp_c | station_precip_mm | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 1990 | 18 | 1990-04-30 | 0.122600 | 0.103725 | 0.198483 | 0.177617 | 12.42 | 297.572857 | ... | 32.00 | 73.365714 | 12.42 | 14.012857 | 2.628571 | 25.442857 | 6.900000 | 29.4 | 20.0 | 16.0 |
| 1 | 0 | 1990 | 19 | 1990-05-07 | 0.169900 | 0.142175 | 0.162357 | 0.155486 | 22.82 | 298.211429 | ... | 17.94 | 77.368571 | 22.82 | 15.372857 | 2.371429 | 26.714286 | 6.371429 | 31.7 | 22.2 | 8.6 |
| 2 | 0 | 1990 | 20 | 1990-05-14 | 0.032250 | 0.172967 | 0.157200 | 0.170843 | 34.54 | 298.781429 | ... | 26.10 | 82.052857 | 34.54 | 16.848571 | 2.300000 | 26.714286 | 6.485714 | 32.2 | 22.8 | 41.4 |
| 3 | 0 | 1990 | 21 | 1990-05-21 | 0.128633 | 0.245067 | 0.227557 | 0.235886 | 15.36 | 298.987143 | ... | 13.90 | 80.337143 | 15.36 | 16.672857 | 2.428571 | 27.471429 | 6.771429 | 33.3 | 23.3 | 4.0 |
| 4 | 0 | 1990 | 22 | 1990-05-28 | 0.196200 | 0.262200 | 0.251200 | 0.247340 | 7.52 | 299.518571 | ... | 12.20 | 80.460000 | 7.52 | 17.210000 | 3.014286 | 28.942857 | 9.371429 | 35.0 | 23.9 | 5.8 |
5 rows × 24 columns
Esta transformación de la variable categórica 'city' en numérica correspondería realizarlo en la subsección de transformación, pero lo realizo en este punto porque me aporta una ventaja para realizar la gráfica de dispersión 2 a 2 con pairplot en breve.
Análisis univariante (histogramas/percentiles)¶
La visualización de histogramas permite observar la distribución de las variables en el conjunto de datos y detectar posibles sesgos, outliers o patrones interesantes para explorar en el análisis posterior.
# Histogramas de las variables numéricas
train.drop(['city', 'year', 'weekofyear'], axis=1).hist(figsize=(20,15), bins=50)
plt.suptitle('Histogramas de las características', fontsize = 20)
plt.tight_layout()
plt.show()
De los histogramas anteriores, se observa que algunas variables ambientales relacionadas con la vegetación, como 'ndvi_ne', 'ndvi_nw', 'ndvi_se' y 'ndvi_sw', siguen distribuciones más o menos simétricas, similares a la forma de una campana de Gauss, lo que sugiere una distribución normal o ligeramente sesgada. Por otro lado, variables como 'precipitation_amt_mm', 'reanalysis_precip_amt_kg_per_m2', y 'station_precip_mm' muestran distribuciones asimétricas, sesgadas hacia la derecha, lo que indica que los eventos extremos de lluvia son menos comunes pero pueden tener un impacto significativo. Las variables relacionadas con la temperatura, como 'reanalysis_avg_temp_k' y 'station_avg_temp_c', tienden a tener distribuciones más uniformes con algún grado de sesgo, lo que es habitual en datos de temperatura donde se observa un rango estable alrededor de la media, con variaciones dependientes del clima local. Mientras otras variables de temperatura, como 'station_max_temp_c', presentan un rango más amplio en comparación con 'reanalysis_tdtr_k', reflejando diferentes características de medición climática.
Es importante señalar que las variables de temperatura están medidas en distintas escalas: Celsius en algunos casos y Kelvin en otros. Esta diferenicia de unidades debe ser considerada en el análisis y también requiere un posterior escalado y/o normalizado.
Los patrones de distribución observados serán importantes para la selección de características y el preprocesamiento de los datos para el posterior modelado predictivo.
En los histogramas se han detectado posibles outliers, para una comprensión más profunda de estos se realizan los diagramas de caja o boxplot de todas las variables numéricas, que muestran la distribución de los datos a través de cuartiles y percentiles.
La caja representa el rango intercuartílico (IQR), que contiene el 50% central de los datos (entre el percentil 25 y 75). Los bigotes se extienden hasta los valores mínimo y máximo dentro de un rango definido (generalmente 1.5 veces el IQR desde la caja). Los puntos fuera de los bigotes se consideran valores atípicos/outliers.
# Diagramas de caja (boxplot) de las variables numéricas
nc = train.columns[4:23].tolist()
plt.figure(figsize=[20, 15])
plt.suptitle('Boxplots de las características', fontsize = 20)
for c in range(len(nc)):
plt.subplot(math.ceil(len(nc)/4), 4, c+1)
train.boxplot(nc[c])
plt.tight_layout()
plt.show()
Los outliers o valores atípicos son los que se observan fuera de los bigotes de las respectivas cajas de cada variable (1.5 veces el IQR desde Q1 y Q3). Los boxplots anteriores muestran que las variables relacionadas con la vegetación 'ndvi_xx' presentan distribuciones simétricas y estables, con pocos outliers. Las variables de precipitación como 'precipitation_amt_mm' y 'reanalysis_precip_amt_kg_per_m2' tienen distribuciones sesgadas hacia valores bajos, con numerosos valores atípicos en el extremo superior, lo que indica eventos de precipitación extrema. Las variables de temperatura, tanto en Celsius como Kelvin, presentan distribuciones más compactas, con pocos outliers, lo que refleja estabilidad en las condiciones de temperatura. Las variables de humedad muestran un comportamiento similar, con valores concentrados y algunos outliers que podrían señalar eventos de baja humedad. Las variables de precipitación y algunas de temperatura muestran mayor cantidad de valores atípicos, lo que sugiere que deben ser tratados cuidadosamente más adelante.
Análisis bivariante (diagramas de dispersión 2 a 2)¶
# Visualización de los gráficos de dispersión del dataset tratado con pairplot
sns.pairplot(data=train.drop(['year', 'weekofyear'], axis=1), hue='city')
plt.suptitle('Diagramas de dispersión 2 a 2', fontsize = 20, y=1.02)
plt.show()